// v1^2-v0^=2ax
//
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
#include<climits>
#define int long long
using namespace std;
struct fasta
{
    int l,r;
    bool operator <(const fasta &x)const{
        if(l != x.l)return l<x.l;
        else return r<x.r;
    }
};
fasta judge(int l,int v,int a,int L,int vmax)
{
    if(a==0)
    {
        if(v<=vmax)return{-1,-1};
        if(v>vmax)return{l,L};
    }
    if(a<0)
    {
        if(v<=vmax)return{-1,-1};
        int p=l+(v*v-vmax*vmax)/(2*abs(a));
        if(1.0*p-1.0*(l+(v*v-vmax*vmax)/(2*abs(a)))==0)return{l,max(l,l+(v*v-vmax*vmax)/(2*abs(a))-1)};
        return{l,l+(v*v-vmax*vmax)/(2*abs(a))};
    }
    if(a>0)
    {
        if(v>vmax)return{l,L};
        if(v==vmax)return{l+1,L};
        if(v<vmax)return{l+(int)ceil(1.0*(vmax*vmax-v*v)/(2*a)),L};
    }
}
long long f[3500][3500];
long long minn[4000];
void solve()
{
    int L,vmax;
    int n,m;
    vector<fasta> edges;
    cin>>n>>m>>L>>vmax;
    vector<int> road(L+100);
    vector<int> qian(L+100);
    vector<int> heads;
    vector<fasta> dectected;
    for(int i=1;i<=n;i++)
    {
       int d,v,a;
       cin>>d>>v>>a;
       fasta now=judge(d,v,a,L,vmax);
       if(now.l!=-1 && now.r !=-1)
       {
           edges.push_back(now);
       }
    }
    sort(edges.begin(),edges.end());
    for(int i=1;i<=m;i++)
    {
        int p;
        cin>>p;
        heads.push_back(p);
        road[p]++;
    }
    sort(heads.begin(),heads.end());
    for(int i=1;i<=L;i++)
    {
        qian[i]=qian[i-1]+road[i];
    }
    for(auto i: edges)
    {
        if(i.l==0)
        {
            if(qian[i.r]>0)dectected.push_back(i);
        }
        else
        {
            if(qian[i.r]-qian[i.l-1]>0)dectected.push_back(i);
        }
    }

    cout<<dectected.size()<<" ";

    for(int i=0;i<=max(dectected.size(),heads.size())+10;i++)
    {
        for(int j=0;j<=max(dectected.size(),heads.size())+10;j++)
        {
            f[i][j]=heads.size();
            minn[i]=heads.size();
            if(i==0)f[i][j]=1;
        }
    }

    /* for(auto i:dectected)
    {
        cout<<i.l<<" "<<i.r<<endl;
    } */

    for(int i=1;i<=dectected.size();i++)
    {
        for(int j=1;j<=heads.size();j++)
        {
            bool tag=false;
            if(dectected[i-1].l<= heads[j-1] && heads[j-1]<=dectected[i-1].r)
                tag=true;//if this camra can detect the No.i car
            if(tag)f[i][j]=min(f[i][j],min(minn[i-1]+1,f[i-1][j]));
            minn[i]=min(minn[i],f[i][j]);
        }
    }
    /* for(int i=1;i<=dectected.size();i++)
    cout<<minn[i]<<endl; */
    cout<<m-minn[dectected.size()];

    return;
}
signed main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    cin>>T;
    while(T--)
        solve();
    return 0;
}